﻿package zf.ui
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	
	import zf.ui.MouseMoveEvent;
	
	/**
	 * 开始事件 
	 * @eventType zf.ui.MouseMoveEvent.START
	 */
	[Bindable]
	[Event(name="start", type="zf.ui.MouseMoveEvent")]
	/**
	 * 停止事件 
	 * @eventType zf.ui.MouseMoveEvent.STOP
	 */
	[Bindable]
	[Event(name="stop", type="zf.ui.MouseMoveEvent")]
	/**
	 * 更新事件 
	 * @eventType zf.ui.MouseMoveEvent.UPDATE
	 */
	[Bindable]
	[Event(name="update", type="zf.ui.MouseMoveEvent")]

	/**
	 * MouseMove 类,以实现鼠标滑动过程测算处理，适用于触摸屏滑动事件处理。 
	 * @author mike.zhang
	 * @langversion 3.0 
	 * @playerversion Flash 9 
	 */
	public class MouseMove extends Sprite
	{
		private var _enabled:Boolean=false;

		private var _live:Boolean=false;
		private var _minUint:uint=30;

		private var _interval:uint=3;

		private var _itf:Function;

		private var startx:Number;
		private var starty:Number;
		private var frame:uint=0;
		
		private var _run:Boolean=false;
		

		/**
		 * 创建一个 MouseMove 类 
		 * 
		 */
		public function MouseMove ():void
		{
			_itf=new Function;
			
			addEventListener(Event.ADDED_TO_STAGE,start);
			
			addEventListener(Event.REMOVED_FROM_STAGE,removeEvent);
		}
		/**
		 * 是否在运行 
		 * @return 
		 * 
		 */
		public function get run():Boolean
		{
			return _run;
		}

		/**
		 * 是否启用 
		 * @return 
		 * 
		 */
		public function get enabled ():Boolean
		{
			return _enabled;
		}
		
		
		/**
		 * 设置是否启动 
		 * @param value true为启用，false不启用
		 * @return 设置成功返回true
		 * 
		 */
		public function setEnabled (value:Boolean):Boolean
		{
			if(!stage)
			{
				return false;
			}
			if (_enabled!=value)
			{
				_enabled = value;
				if (_enabled)
				{
					if (!stage.hasEventListener(MouseEvent.MOUSE_DOWN))
					{
						stage.addEventListener (MouseEvent.MOUSE_DOWN,mouseMoveOnMouseEvent);
					}
					if (!stage.hasEventListener(MouseEvent.MOUSE_UP))
					{
						stage.addEventListener (MouseEvent.MOUSE_UP,mouseMoveOnMouseEvent);
					}
				}
				else
				{
					if (stage.hasEventListener(MouseEvent.MOUSE_DOWN))
					{
						stage.removeEventListener (MouseEvent.MOUSE_DOWN,mouseMoveOnMouseEvent);
					}
					if (stage.hasEventListener(MouseEvent.MOUSE_UP))
					{
						stage.removeEventListener (MouseEvent.MOUSE_UP,mouseMoveOnMouseEvent);
					}
				}
			}
			return true;
		}

		/**
		 * 是否连续触发 
		 * @return 
		 * 
		 */
		public function get live ():Boolean
		{
			return _live;
		}

		public function set live (value:Boolean):void
		{
			_live = value;
		}

		/**
		 * 触发最小像素距离
		 * @return 
		 * 
		 */
		public function get minUint ():uint
		{
			return _minUint;
		}

		public function set minUint (value:uint):void
		{
			_minUint = value;
		}

		/**
		 * 以桢为单位的间隔数，每interval触发一次
		 * @return 
		 * 
		 */
		public function get interval ():uint
		{
			return _interval;
		}

		public function set interval (value:uint):void
		{
			_interval = value;
		}
		/**
		 * 间隔调用函数;ITF函数必须有2个参数 ITF(dx:Number,dy:Number):Void，两个参数分别指代在x轴和y轴上距离的变化量，正的dx表示向右运动，负的向左；正的dy表示向下运动，负的向上。
		 * @return 
		 * 
		 */
		public function get ITF ():Function
		{
			return _itf;
		}
		public function set ITF (value:Function):void
		{
			_itf=value;
		}
		/**
		 * 获得统计起始点 
		 * @return 
		 * 
		 */
		public function getStartPoint():Point
		{
			return new Point(startx,starty);
		}
		private function start (e:Event):void
		{
			removeEventListener(Event.ADDED_TO_STAGE,start);
			_enabled=true;

			stage.addEventListener (MouseEvent.MOUSE_DOWN,mouseMoveOnMouseEvent);
			stage.addEventListener (MouseEvent.MOUSE_UP,mouseMoveOnMouseEvent);

		}
		private function mouseMoveOnMouseEvent (e:MouseEvent):void
		{
			switch (e.type)
			{
				case MouseEvent.MOUSE_DOWN :
					
					createEnterFrame ();
					dispatchEvent(new MouseMoveEvent(MouseMoveEvent.START,new Point(startx,starty)));
					break;
				case MouseEvent.MOUSE_UP :
					
					
					if(_run)
					{
						dispatchEvent(new MouseMoveEvent(MouseMoveEvent.STOP,new Point(stage.mouseX,stage.mouseY)));
					}
					clearEnterFrame ();
					break;
			}
		}
		private function createEnterFrame ():void
		{
			startx=stage.mouseX;
			starty=stage.mouseY;
			_run=true;
			if (hasEventListener(Event.ENTER_FRAME)==false)
			{
				frame=0;
				addEventListener (Event.ENTER_FRAME,onEnterFrameEvent);
			}
		}
		private function clearEnterFrame ():void
		{
			_run=false;
			if (hasEventListener(Event.ENTER_FRAME))
			{
				removeEventListener (Event.ENTER_FRAME,onEnterFrameEvent);
			}
		}
		private function onEnterFrameEvent (e:Event):void
		{
			if (frame<_interval)
			{
				frame++;
				return;
			}
			else
			{
				frame=0;
			}
			var dx:Number=stage.mouseX-startx;
			var dy:Number=stage.mouseY-starty;
			/*if(_live)
			{
				startx=stage.mouseX;
				starty=stage.mouseY;
			}*/
			if (Math.abs (dx) > _minUint || Math.abs (dy) > _minUint)
			{
				createEvent (dx,dy);
				if (!_live)
				{
					clearEnterFrame ();
				}
			}
		}
		protected function createEvent (dx:Number,dy:Number):void
		{
			dispatchEvent(new MouseMoveEvent(MouseMoveEvent.UPDATE,new Point(dx,dy)));
			_itf (dx,dy);
		}
		/**
		 * 停止本次操作 
		 * 
		 */
		public function stop():void
		{
			clearEnterFrame();
		}
		
		/**
		 * 清除 
		 * @param e
		 * 
		 */
		public function remove():void
		{
			removeEvent();
		}
		private function removeEvent(e:Event=null):void
		{
			//trace("MouseMove is Down.");
			if (stage.hasEventListener(MouseEvent.MOUSE_DOWN))
			{
				stage.removeEventListener (MouseEvent.MOUSE_DOWN,mouseMoveOnMouseEvent);
			}
			if (stage.hasEventListener(MouseEvent.MOUSE_UP))
			{
				stage.removeEventListener (MouseEvent.MOUSE_UP,mouseMoveOnMouseEvent);
			}
			
			clearEnterFrame();
			if(hasEventListener(Event.REMOVED_FROM_STAGE))
			{
				removeEventListener(Event.REMOVED_FROM_STAGE,remove);
			}
		}

	}
}